namespace Microsoft.Sdc.Tasks.BizTalk2004.Rules
{
    using System;
    using System.Collections;
    using Microsoft.Build.Framework;
    using Microsoft.RuleEngine;
    using Microsoft.RuleEngine.RemoteUpdateService;
    using System.Globalization;

    /// <summary>
    /// Checks if a Rule policy exists in the RulesEngine database
    /// </summary>
    /// <remarks>
    /// <code>
    /// <![CDATA[<BizTalk2004.Rules.Exits Name="displayName" Version="" RulesServer="server" RulesDatabase="database" />]]>
    /// </code>
    /// <para>where:</para>
    /// <para><i>Name (Required)</i></para>
    /// <para>
    /// The name of the Rule policy.
    /// </para>
    /// <para><i>Version</i></para>
    /// <para>
    /// The version of the rule policy.
    /// </para>
    /// <para><i>RulesServer</i></para>
    /// <para>
    /// The name of the BizTalk RulesEngine database server. If neither this nor the server name are specified 
    /// then the installation will default to the local installation.
    /// </para>
    /// <para><i>RulesDatabase</i></para>
    /// <para>
    /// The name of the BizTalk RulesEngine database. If neither this nor the server name are specified 
    /// then the installation will default to the local installation.
    /// </para>
    /// <para><i>PolicyExists (output)</i></para>
    /// <para>
    /// The result indicating if the policy exists in the BizTalk RulesEngine database.
    /// </para>
    /// </remarks>
    /// <example>
    /// <code><![CDATA[
    /// <Project>
    ///     <Target Name="Test" >
    ///         <BizTalk2004.Rules.Exists
    ///             Name="BizTalkRulesPolicy"
    ///             Version="1.0"
    ///             Server="." 
    ///             Database="BizTalkRulesDb">
    ///             <Output TaskParameter="DoesExist" PropertyName="PolicyExists" />
    ///         </BizTalk2004.Rules.Exists>
    ///     </Target>
    /// </Project>
    /// ]]></code>    
    /// </example>
    public class Exists : TaskBase
    {

        #region Private Members

        private string rulesDatabase;
        private string rulesServer;
        private string name;
        private string version;
        private bool exists;

        #endregion

        #region Public Properties

        /// <summary>
        /// Gets or sets the name of the deployed policy (ruleset).
        /// </summary>
        /// <value>
        /// The name of the policy (ruleset).
        /// </value>
        [Required]
        public string Name
        {
            get
            {
                return this.name;
            }
            set
            {
                this.name = value;
            }
        }

        /// <summary>
        /// Gets whether the deployed policy (ruleset) exists
        /// </summary>
        /// <value><b>true</b> If the policy is exists <b>false</b> otherwise.</value>
        [Output]
        public bool PolicyExists
        {
            get { return this.exists; }
            protected set { this.exists = value; }
        }

        /// <summary>
        /// Gets or sets the version of the deployed policy (ruleset).
        /// </summary>
        /// <value>
        /// The version of the policy (ruleset).
        /// If no version is filled, default the latest version is set.
        /// </value>
        public string Version
        {
            get
            {
                return this.version;
            }
            set
            {
                this.version = value;
            }

        }

        /// <summary>
        /// Gets or sets the name of the BizTalk Rules Engine database.
        /// </summary>
        /// <value>
        /// The name of the BizTalk Rules Engine database.
        /// </value>
        public string RulesDatabase
        {
            get { return this.rulesDatabase; }
            set { this.rulesDatabase = value; }
        }

        /// <summary>
        /// Gets or sets the logical name of the server hosting the BizTalk Rules Engine database.
        /// </summary>
        /// <value>
        /// The logical name of the server hosting the BizTalk Rules Engine database.
        /// </value>
        public string RulesServer
        {
            get { return this.rulesServer; }
            set { this.rulesServer = value; }
        }

        #endregion

        protected override void InternalExecute()
        {
            string rulesServer = string.IsNullOrEmpty(this.rulesServer) ? Configuration.DatabaseServer : this.rulesServer;
            string rulesDatabase = string.IsNullOrEmpty(this.rulesDatabase) ? Configuration.DatabaseName : this.rulesDatabase;

            // Get the interface to import / publish / deploy / undeploy rulesets
            IRuleSetDeploymentDriver dd;

            ArrayList list = new ArrayList();
            list.Add(rulesServer);
            list.Add(rulesDatabase);

            try
            {
                // Get the Remote Interface so it is possible to set a remote database
                dd = (IRuleSetDeploymentDriver)RemoteUpdateService.LocateObject(Configuration.DeploymentDriverClass, Configuration.DeploymentDriverDll, list.ToArray());

                // Get The rule store to seek for the policy (ruleset)
                RuleStore store = dd.GetRuleStore();

                foreach(RuleSetInfo ruleInfo in store.GetRuleSets(this.Name, RuleStore.Filter.All))
                {
                    if (!string.IsNullOrEmpty(this.Version))
                    {
                        // Create the versionnumber
                        string currentVersion = ruleInfo.MajorRevision + "." + ruleInfo.MinorRevision;

                        if (currentVersion == this.Version)
                        {
                            Log.LogMessage(string.Format(CultureInfo.InvariantCulture, "RuleSet : {0} with version {1} found", this.Name, this.Version));
                            this.PolicyExists = true;
                            break;
                        }
                    }
                    else
                    {
                        Log.LogMessage(string.Format(CultureInfo.InvariantCulture, "RuleSet : {0} found", this.Name));               
                        this.PolicyExists = true;
                        break;
                    }
                }
            }
            catch (Exception ex)
            {
                // An error occurred during the location of the object, or the import and publish of 
                // the ruleset

                throw new TaskException(ex, "Microsoft.Sdc.Tasks.BizTalk2004.Rules::Exists");
            }
        }

    }
}
